package com.share.module.sys.file.web;

import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.share.module.sys.file.entity.FileEntity;
import com.share.module.sys.file.service.FileService;
import com.stock.common.response.ApiResult;
import com.stock.mybatisplus.utils.PageUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/file")
@Tag(name = "文件管理", description = "文件上传、下载、管理接口")
public class FileController {

    @Value("${files.upload.path}")
    private String fileUploadPath;

    @Value("${server.ip}")
    private String ip;

    @Resource
    private FileService fileService;

    @GetMapping("/page")
    @Operation(summary = "分页查询", description = "分页查询文件列表")
    public ApiResult<PageUtils<FileEntity>> findPage(@Parameter(description = "当前页", required = true, example = "1") @RequestParam(defaultValue = "1") Integer current,
                                         @Parameter(description = "每页个数", required = true, example = "10") @RequestParam(defaultValue = "10") Integer size,
                                         @Parameter(description = "文件名称") @RequestParam(defaultValue = "") String name) {
        PageUtils<FileEntity> page = fileService.page(current, size, name);
        return ApiResult.success(page);
    }

    @PostMapping("/update")
    @Operation(summary = "更新根据id", description = "根据id更新文件信息")
    public ApiResult<Boolean> update(@Parameter(description = "文件实体") @RequestBody FileEntity file) {
        boolean updateById = fileService.updateById(file);
        if (updateById) {
            return ApiResult.success(updateById);
        } else {
            return ApiResult.error("更新失败");
        }
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除", description = "根据id删除文件")
    public ApiResult<Boolean> delete(@Parameter(description = "文件ID") @PathVariable Integer id) {
        FileEntity file = fileService.getById(id);
        file.setFlagDel(true);
        boolean updateById = fileService.updateById(file);
        if (updateById) {
            return ApiResult.success(updateById);
        } else {
            return ApiResult.error("删除失败");
        }
    }

    @PostMapping("/del/batch")
    @Operation(summary = "批量删除", description = "批量删除文件")
    public ApiResult<Boolean> batchDel(@Parameter(description = "文件ID列表") @RequestBody List<Integer> ids) {
        boolean removeByIds = fileService.removeByIds(ids);
        if (removeByIds) {
            return ApiResult.success(removeByIds);
        } else {
            return ApiResult.error("批量删除失败");
        }
    }

    @PostMapping("/upload")
    @Operation(summary = "上传", description = "上传文件到服务器")
    public ApiResult<String> upload(@Parameter(description = "文件") @RequestParam MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String type = originalFilename.substring(originalFilename.lastIndexOf("."));
        long size = file.getSize();

        // 先存储到磁盘
        String uuid = UUID.randomUUID().toString();
        String fileUUID = uuid + type;
        File uploadFile = new File(fileUploadPath + fileUUID);
        if (!uploadFile.getParentFile().exists()) {
            uploadFile.getParentFile().mkdirs();
        }

        String url;
        file.transferTo(uploadFile);
        String md5 = SecureUtil.md5(uploadFile);

        FileEntity dbFile = fileService.getOne(Wrappers.<FileEntity>lambdaQuery().eq(FileEntity::getMd5, md5));
        if (dbFile != null) {
            url = dbFile.getUrl();
        } else {
            url = "http://" + ip  + ":8090/file/" + fileUUID;
        }

        // 再存储到数据库
        FileEntity files = new FileEntity();
        files.setName(fileUUID);
        files.setType(type);
        files.setSize(size / 1024);
        files.setUrl(url);
        files.setMd5(md5);
        fileService.save(files);

        return ApiResult.success(url);
    }

    @GetMapping("/{fileUUID}")
    @Operation(summary = "下载", description = "根据文件UUID下载文件")
    public void download(@Parameter(description = "文件UUID") @PathVariable String fileUUID, HttpServletResponse response) throws IOException {
        File uploadFile = new File(fileUploadPath + fileUUID);
        ServletOutputStream os = response.getOutputStream();
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
        response.setContentType("application/octet-stream");

        os.write(FileUtil.readBytes(uploadFile));
        os.flush();
        os.close();
    }

}
